package com.jiangyao.service.impl;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jiangyao.common.constants.AdminUserConstants;
import com.jiangyao.common.constants.ConfigConstants;
import com.jiangyao.common.constants.SystemConstants;
import com.jiangyao.common.exception.ServerException;
import com.jiangyao.common.utils.FtpClient;
import com.jiangyao.common.utils.MD5util;
import com.jiangyao.common.utils.StringUtils;
import com.jiangyao.dao.IOrgInfoDao;
import com.jiangyao.model.dto.OrgInfoDto;
import com.jiangyao.model.dto.backend.OrgInfoDTO;
import com.jiangyao.model.dto.backend.OrgInfoListPageDTO;
import com.jiangyao.model.dto.backend.OrgInfoSearchDTO;
import com.jiangyao.model.entity.AdminUser;
import com.jiangyao.model.entity.AdminUserOrgClass;
import com.jiangyao.model.entity.OrgInfo;
import com.jiangyao.model.vo.AdminUserSessionVO;
import com.jiangyao.model.vo.UserSessionVO;
import com.jiangyao.model.vo.backend.AdminUserBaseVO;
import com.jiangyao.model.vo.backend.OrgInfoExportVO;
import com.jiangyao.model.vo.backend.OrgInfoListVO;
import com.jiangyao.model.vo.backend.OrgInfoVO;
import com.jiangyao.service.AdminUserOrgClassService;
import com.jiangyao.service.AdminUserService;
import com.jiangyao.service.ConfigService;
import com.jiangyao.service.OrgInfoService;
import lombok.extern.slf4j.Slf4j;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 组织信息 服务实现类
 * </p>
 *
 * @author xiangyan
 * @since 2020-08-12
 */
@Slf4j
@Service
public class OrgInfoServiceImpl extends BaseServiceImpl<IOrgInfoDao, OrgInfo> implements OrgInfoService {

    @Autowired
    private IOrgInfoDao orgInfoDao;
    @Autowired
    private AdminUserService adminUserService;
    @Autowired
    private AdminUserOrgClassService adminUserOrgClassService;
    @Autowired
    private DozerBeanMapper dozerBeanMapper;
    @Autowired
    private ConfigService configService;


    @Override
    public List<OrgInfo> getList(OrgInfoDto orgInfoDto) {
        QueryWrapper<OrgInfo> params = new QueryWrapper<>();
        if (StringUtils.isNotEmpty(orgInfoDto.getOrgName())) {
            params.like("org_name", orgInfoDto.getOrgName());
        }
        if (orgInfoDto.getStatus() != null) {
            params.like("status", orgInfoDto.getStatus());
        }
        return this.list(params);
    }

    @Override
    public List<OrgInfo> getSessionUserOrg() {
        UserSessionVO user = getApiLoginSession();
        if (user == null ||  user.getOrgIdList()==null ||  user.getOrgIdList().isEmpty()) {
            return null;
        }
        List<Integer> orgList = user.getOrgIdList();
        QueryWrapper<OrgInfo> params = new QueryWrapper<>();
        params.in("org_id", orgList);
        List<OrgInfo> result = this.list(params);
        if (!CollectionUtils.isEmpty(result)) {
            result.forEach(r -> r.setOrgLogo(FtpClient.fullFtpUrl(r.getOrgLogo())));
        }
        return result;
    }

    @Override
    public OrgInfo getOrgDetail(Integer orgId) {
        QueryWrapper<OrgInfo> orgInfoQueryWrapper = new QueryWrapper<>();
        orgInfoQueryWrapper.eq("org_id", orgId);
        return this.getOne(orgInfoQueryWrapper);
    }

    @Override
    public Page<OrgInfoListVO> getListPage(OrgInfoListPageDTO orgInfoListPageDTO) {
        // 登录用户信息
        AdminUserSessionVO adminUserSessionVO = getAdminLoginSession();
        // 当前登录用户管理的组织ID集合(业务数据权限)
        orgInfoListPageDTO.setOrgIdList(adminUserSessionVO.getOrgIdList());

        Page<OrgInfoListVO> page = new Page<>(orgInfoListPageDTO.getPageNo(), orgInfoListPageDTO.getPageSize());
        Page<OrgInfoListVO> result = orgInfoDao.getListPage(page, orgInfoListPageDTO);
        if (CollectionUtils.isEmpty(result.getRecords())) {
            return result;
        }
        result.getRecords().forEach(vo -> {
            if (StringUtils.isNotEmpty(vo.getOrgLogo())) {
                vo.setOrgLogo(FtpClient.fullFtpUrl(vo.getOrgLogo()));
            }
        });
        return result;
    }

    @Override
    public void add(OrgInfoDTO orgInfoDTO) {
        // 检查重名
        OrgInfo orgInfoByOrgName = getOneByOrgName(orgInfoDTO.getOrgName());
        if (orgInfoByOrgName != null) {
            throw new ServerException(100, "组织名已存在");
        }
        // 处理组织管理员,返回新的管理员ID
        Integer manageAdminUserId = handleManageAdmin(orgInfoDTO);
        Date now = new Date();
        OrgInfo orgInfo = dozerBeanMapper.map(orgInfoDTO, OrgInfo.class);
        orgInfo.setStatus(1);
        orgInfo.setCreateTime(now);
        orgInfo.setCreateAdminId(getLoginAdminUserId());
        orgInfoDao.insert(orgInfo);
        // 增加组织管理员
        AdminUserOrgClass adminUserOrgClass = new AdminUserOrgClass();
        adminUserOrgClass.setAdminId(manageAdminUserId);
        adminUserOrgClass.setOrgId(orgInfo.getOrgId());
        adminUserOrgClass.setCreateTime(now);
        adminUserOrgClassService.save(adminUserOrgClass);
    }

    /**
     * 处理组织管理员
     *
     * @param orgInfoDTO 组织信息DTO
     * @return 结果
     */
    private Integer handleManageAdmin(OrgInfoDTO orgInfoDTO) {
        Integer orgId = orgInfoDTO.getOrgId();
        // 以前的管理员ID
        Integer preAdminUserId = null;
        Integer manageAdminUserId = orgInfoDTO.getManageAdminUserId();
        // 编辑组织
        if (orgId != null && orgId != 0) {
            // 获取以前的管理员ID
            preAdminUserId = adminUserOrgClassService.getAdminUserId(orgId, null);
            // 管理员没修改
            if (preAdminUserId != null && preAdminUserId.equals(manageAdminUserId)) {
                return manageAdminUserId;
            }
        }

        // 选择已有管理员
        if (manageAdminUserId != null && manageAdminUserId != 0) {
            AdminUser adminUser = adminUserService.getById(manageAdminUserId);
            if (adminUser == null || adminUser.getStatus() != 1) {
                throw new ServerException(100, "管理员不存在或不可用");
            }
        } else {
            // 新增管理员
            if (StringUtils.isEmpty(orgInfoDTO.getManageLoginName()) || StringUtils.isEmpty(orgInfoDTO.getManageName())) {
                throw new ServerException(100, "管理员账号、姓名不能为空");
            }
            AdminUser adminUser = adminUserService.getByLoginName(orgInfoDTO.getManageLoginName());
            if (adminUser != null) {
                throw new ServerException(100, "管理员账号已存在");
            }
            adminUser = AdminUser.builder().loginName(orgInfoDTO.getManageLoginName()).adminName(orgInfoDTO.getManageName())
                    .password(MD5util.generateSymbol(AdminUserConstants.DEFAULT_PASSWORD)).phone(orgInfoDTO.getManagePhone())
                    .adminPhoto(SystemConstants.USER_HEAD_DEFAULT).status(1).createTime(new Date()).createAdminId(getLoginAdminUserId())
                    .build();
            adminUserService.save(adminUser);
            manageAdminUserId = adminUser.getAdminId();
        }

        List<Integer> roleIdList;
        // 学校
        if (orgInfoDTO.getOrgType() == 1) {
            roleIdList = AdminUserConstants.SCHOOL_ORG_ADMIN_ROLE_ID_LIST;
        } else {
            // 企业
            roleIdList = AdminUserConstants.ENTERPRISE_ORG_ADMIN_ROLE_ID_LIST;
        }
        adminUserService.saveAdminRole(manageAdminUserId, roleIdList);
        // 编辑组织，组织以前管理员不为空
        if (orgId != null && preAdminUserId != null) {
            QueryWrapper<AdminUserOrgClass> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("org_id", orgId);
            adminUserOrgClassService.remove(queryWrapper);
        }
        return manageAdminUserId;
    }


    @Override
    public void edit(OrgInfoDTO orgInfoDTO) {
        OrgInfo orgInfo = this.getById(orgInfoDTO.getOrgId());
        if (orgInfo == null) {
            throw new ServerException(100, "该组织不存在");
        }
        // 修改组织名称，检查重名
        if (!orgInfo.getOrgName().equals(orgInfoDTO.getOrgName())) {
            OrgInfo orgInfoByOrgName = getOneByOrgName(orgInfoDTO.getOrgName());
            if (orgInfoByOrgName != null) {
                throw new ServerException(100, "组织名已存在");
            }
        }
        // 处理组织管理员,返回新的管理员ID
        Integer manageAdminUserId = handleManageAdmin(orgInfoDTO);
        Date now = new Date();
        BeanUtils.copyProperties(orgInfoDTO, orgInfo, "orgType", "createTime", "createAdminId", "status");
        orgInfo.setUpdateTime(now);
        orgInfo.setUpdateAdminId(getLoginAdminUserId());
        orgInfoDao.updateById(orgInfo);

        // 获取以前的管理员ID
        Integer preAdminUserId = adminUserOrgClassService.getAdminUserId(orgInfoDTO.getOrgId(), null);
        // 增加组织管理员
        if (preAdminUserId == null || !preAdminUserId.equals(manageAdminUserId)) {
            AdminUserOrgClass adminUserOrgClass = new AdminUserOrgClass();
            adminUserOrgClass.setAdminId(manageAdminUserId);
            adminUserOrgClass.setOrgId(orgInfo.getOrgId());
            adminUserOrgClass.setCreateTime(now);
            adminUserOrgClassService.save(adminUserOrgClass);
        }
    }

    @Override
    public void editStatus(OrgInfoDTO orgInfoDTO) {
        UpdateWrapper<OrgInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.in("org_id", orgInfoDTO.getOrgIdList());
        updateWrapper.set("status", orgInfoDTO.getStatus() != null ? orgInfoDTO.getStatus() : 1);
        updateWrapper.set("update_time", new Date());
        updateWrapper.set("update_admin_id", getLoginAdminUserId());
        this.update(updateWrapper);
    }

    /**
     * 根据组织名获取组织
     *
     * @param orgName 组织名称
     * @return 结果
     */
    private OrgInfo getOneByOrgName(String orgName) {
        if (StringUtils.isBlank(orgName)) {
            return null;
        }
        QueryWrapper<OrgInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("org_name", orgName);
        queryWrapper.last(" LIMIT 1");
        return this.getOne(queryWrapper);
    }

    @Override
    public OrgInfoVO getDetail(OrgInfoDTO orgInfoDTO) {
        OrgInfo orgInfo = this.getById(orgInfoDTO.getOrgId());
        if (orgInfo == null) {
            throw new ServerException(100, "该组织不存在");
        }
        OrgInfoVO orgInfoVO = dozerBeanMapper.map(orgInfo, OrgInfoVO.class);
        if (StringUtils.isNotEmpty(orgInfo.getOrgLogo())) {
            orgInfoVO.setOrgLogoFull(FtpClient.fullFtpUrl(orgInfo.getOrgLogo()));
        }
        AdminUser adminUser = adminUserOrgClassService.getAdminUser(orgInfo.getOrgId(), null);
        if (adminUser != null) {
            orgInfoVO.setAdminUser(dozerBeanMapper.map(adminUser, AdminUserBaseVO.class));
        }
        return orgInfoVO;
    }

    @Override
    public void export(HttpServletResponse response, OrgInfoListPageDTO orgInfoListPageDTO) {
        try {
            // 登录用户信息
            AdminUserSessionVO adminUserSessionVO = getAdminLoginSession();
            // 当前登录用户管理的组织ID集合(业务数据权限)
            orgInfoListPageDTO.setOrgIdList(adminUserSessionVO.getOrgIdList());

            Page<OrgInfoListVO> page = new Page<>(1L, Long.parseLong(configService.getValueFromCache(ConfigConstants.EXCEL_EXPORT_LIMIT)));
            page.setSearchCount(false);
            orgInfoDao.getListPage(page, orgInfoListPageDTO);
            if (CollectionUtils.isEmpty(page.getRecords())) {
                return;
            }
            // 导出租住列表集合
            List<OrgInfoExportVO> exportVOList = new ArrayList<>(page.getRecords().size());
            page.getRecords().forEach(vo -> {
                exportVOList.add(dozerBeanMapper.map(vo, OrgInfoExportVO.class));
            });
            String fileName = URLEncoder.encode("组织列表", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), OrgInfoExportVO.class).sheet("组织列表").doWrite(exportVOList);
        } catch (Exception e) {
            log.error("组织导出失败，error:{}", e.getMessage(), e);
        }
    }

    @Override
    public List<OrgInfo> searchForSelect(OrgInfoSearchDTO searchDTO) {
        QueryWrapper<OrgInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1);
        List<Integer> orgIdList = getAdminLoginSession().getOrgIdList();
        if (!CollectionUtils.isEmpty(orgIdList)) {
            queryWrapper.in("org_id", orgIdList);
        }
        if (StringUtils.isNotBlank(searchDTO.getOrgName())) {
            queryWrapper.like("org_name", searchDTO.getOrgName());
        }
        queryWrapper.orderByDesc("org_id");
        queryWrapper.last(" LIMIT 50");
        return this.list(queryWrapper);
    }

    @Override
    public List<OrgInfo> getAdminOrgList() throws ServerException{
        AdminUserSessionVO adminLoginSession = getAdminLoginSession();
        List<Integer> orgIdList = adminLoginSession.getOrgIdList();
        if(orgIdList != null && orgIdList.size() >0){
            return orgInfoDao.getAdminOrgList(orgIdList);
        }else {
            throw new ServerException(201,"该管理员无归属组织，无法获取组织列表");
        }

    }

}
